;; The first four lines of this file were added by Dracula.
;; They tell DrScheme that this is a Dracula Modular ACL2 program.
;; Leave these lines unchanged so that DrScheme can properly load this file.
#reader(planet "reader.rkt" ("cce" "dracula.plt") "modular" "lang")
(require "ihelpers.lisp")

(module mHelpers
  ; Helper function algorithms taken from:
  ; Max K. Agoston (2005). Computer Graphics and Geometric Modeling:
  ;   Implementation and Algorithms. London: Springer. ISBN 1-85233-818-0. pp. 300–306.
  ;   http://books.google.com/books?id=fGX8yC-4vXUC&pg=PA300#v=onepage&q&f=false
  
  ; Convert from RGB to HSV color model
  ; pre: r - red [0, 255]
  ;      g - green [0, 255]
  ;      b - blue [0, 255]
  ; post: list containing hue, saturation, value in that order
  (defun RGB-to-HSV (r g b)
    (if (or (or (< r 0) (> r 255))
            (or (< g 0) (> g 255))
            (or (< b 0) (> b 255)))
        "Invalid RGB value."
        (let* ((minimum (min (min r g) b))
               (maximum (max (max r g) b))
               (delta   (- maximum minimum))
               (v        maximum))
          (if (= maximum 0)
              (let* ((s 0)  ; All values are 0
                     (h 0)) ; Color is black
                (list h s v))
              (let* ((s (/ delta maximum)))
                (if (= r maximum)
                    (if (= delta 0) ; Check if delta == 0 to avoid division by 0 error.
                        (let* ((h (* (- g b) 60)))
                          (if (< h 0) ; Add 360 to h if h is negative.
                              (list (+ h 360) s v)
                              (list h s v)))
                        (let* ((h (round (* (/ (- g b) delta) 60) 1)))
                          (if (< h 0)
                              (list (+ h 360) s v)
                              (list h s v))))
                    (if (= g maximum)
                        (if (= delta 0)
                            (let* ((h (* (+ (- b r) 2) 60)))
                              (if (< h 0)
                                  (list (+ h 360) s v)
                                  (list h s v)))
                            (let* ((h (round (* (+ (/ (- b r) delta) 2) 60) 1)))
                              (if (< h 0)
                                  (list (+ h 360) s v)
                                  (list h s v))))
                        (if (= delta 0)
                            (let* ((h (* (+ (- r g) 4) 60)))
                              (if (< h 0)
                                  (list (+ h 360) s v)
                                  (list h s v)))
                            (let* ((h (round (* (+ (/ (- r g) delta) 4) 60) 1)))
                              (if (< h 0)
                                  (list (+ h 360) s v)
                                  (list h s v)))))))))))
  
  
  ; Convert from HSV to RGB color model
  ; pre: h - hue [0, 255]
  ;      s - saturation: fraction value between [0, 1]
  ;      v - value [0, 255]
  ; post: list containing red, green, blue values in that order
  (defun HSV-to-RGB (h s v)
    (if (or (or (< h 0) (> h 360))
            (or (< s 0) (> s 1))
            (or (< v 0) (> v 255)))
        "Invalid HSV value."
        (if (= s 0)
            (list v v v) ; Saturation is 0.
            (let* ((h1 (/ h 60))
                   (i  (floor h 60))
                   (f  (- h1 i))
                   (p  (round (* (- 1 s) v) 1))
                   (q  (round (* (- 1 (* s f)) v) 1))
                   (r  (round (* (- 1 (* s (- 1 f))) v) 1)))
              (cond
                ((= i 0) (list v r p))
                ((= i 1) (list q v p))
                ((= i 2) (list p v r))
                ((= i 3) (list p q v))
                ((= i 4) (list r p v))
                ((> i 4) (list v p q)))))))
    
  (export iHelpers))